#include "PA_Driver.h"
#include "hx6203sys.h"
#include "DataProcess.h"
#include "delay.h"
#include "ui.h"

uint16_t INTL485_UART_Count=0;	//串口计数
uint8_t INTL485_UART_Finish=0;
uint8_t INTL485_UART_BUF[128]; 

/*****************PA模块驱动函数*******************/
uint8_t PAElementSendBuf[30];

//ui状态反馈
extern uint8_t NodeState[11];

#define PADebugPrint 1

//获取总控单元 前置PA模块状态
void GetPrePASTA(void)
{
	uint8_t delay,pa;
	
	for(pa=0; pa<2; pa++)
    {
		//发送PA0查询指令
		queryPAElementData(pa);
		//等待PA0返回数据
		delay=8;	//最多等待8ms
		while(delay--)
        {
			delay_ms(1);
			if(INTL485_UART_Finish)
                break;
		}
		//报文解析
		if(INTL_UART_GetData())   //通讯异常
        {
			//标记断联信息
			if(HX6203.Preamp[pa].CommErr < 0xff)  HX6203.Preamp[pa].CommErr++;
            NodeState[pa + 9] = ABNORMAL;
		}
        else    //通信正常
        {
            HX6203.Preamp[pa].CommErr = 0;
            NodeState[pa + 9] = NORMAL;
        }
		INTL485_UART_Count=0;
		INTL485_UART_Finish=0;
        if(NodeState[pa + 9] == NORMAL)
        {
            HX6203.Preamp[pa].Curr = Get_PA_Curr(pa);
            if(pa == 0)HX6203.Preamp[pa].Curr = HX6203.Preamp[pa].Curr/1.22f;
            if(pa == 1)HX6203.Preamp[pa].Curr = HX6203.Preamp[pa].Curr/1.1f;
        }
        else
        {
            HX6203.Preamp[pa].Curr = 0;
        }
		delay_ms(1);
	}
}

//查询数据报文
void queryPAElementData(uint8_t id){
	PAElementSendBuf[0]=0x33;
	PAElementSendBuf[1]=id;
	PAElementSendBuf[2]=0x00;
	PAElementSendBuf[3]=0x33;
	PAElementSendBuf[4]=dataCount(PAElementSendBuf, 4);
	INTL_UART_SendData(PAElementSendBuf,5);
}
//模块复位
void resetPAElementData(uint8_t id,uint8_t mode){
	PAElementSendBuf[0]=0x33;
	PAElementSendBuf[1]=id;
	PAElementSendBuf[2]=0x01;
	PAElementSendBuf[3]=mode;
	PAElementSendBuf[4]=dataCount(PAElementSendBuf, 4);
	INTL_UART_SendData(PAElementSendBuf,5);
}
//控制PA PD
void setPAElementPower(uint8_t id,uint8_t state){
	PAElementSendBuf[0]=0x33;
	PAElementSendBuf[1]=id;
	PAElementSendBuf[2]=0x03;
	PAElementSendBuf[3]=state;
	PAElementSendBuf[4]=dataCount(PAElementSendBuf, 4);
	INTL_UART_SendData(PAElementSendBuf,5);
}
//DAC电压控制
void setPAElementVoltage(uint8_t id,float voltage){
	if(id>1)id=1;
	PAElementSendBuf[0]=0x33;
	PAElementSendBuf[1]=id;
	PAElementSendBuf[2]=0x04;
	uint32Encode(&PAElementSendBuf[3],(uint32_t)*(uint32_t*)&voltage);
	PAElementSendBuf[7]=dataCount(PAElementSendBuf, 7);
	INTL_UART_SendData(PAElementSendBuf,8);
}

void INTL_UART_SendData(uint8_t SendBuf[],uint8_t len){
	uint8_t i;
	for(i=0;i<len;i++)	//发送指令
	{
		USART6->DR=SendBuf[i];
		while((USART6->SR&0X40)==0);
	}
}

//判断INTL_RS485是否接收到数据
//如果已接收，将数据解析
uint8_t INTL_UART_GetData(void){
	uint8_t i,PaNum;
	//未接收
	if(INTL485_UART_Finish==0) return 1;	//未完成
	
	//已经接收
	if(INTL485_UART_BUF[0]!=0x33) return 2;	//帧头错误
	if(dataCheck(INTL485_UART_BUF,INTL485_UART_Count-1)!=0) return 3; //校验错误
		
	//校验通过 开始解析
	if(INTL485_UART_Count==25){	//报文数据
		//读取PA序号
		if(INTL485_UART_BUF[1])PaNum=1;
		else PaNum=0;
		//读取PD
		if(INTL485_UART_BUF[2])HX6203.Preamp[PaNum].PD=1;
		else HX6203.Preamp[PaNum].PD=0;
		//读取温度，使用内存对齐方法，注意大小端转换
		for(i=0;i<4;i++)FloatTo4Byte.ByteData[i]=INTL485_UART_BUF[7-i];
		HX6203.Preamp[PaNum].Temp=FloatTo4Byte.floatData;
		//读取栅压，使用内存对齐方法，注意大小端转换
		for(i=0;i<4;i++)FloatTo4Byte.ByteData[i]=INTL485_UART_BUF[11-i];
		HX6203.Preamp[PaNum].Vbias=FloatTo4Byte.floatData;
	}
	//已经接收

	return 0;
}

//ch=0 PA0
//ch=1 PA1
float Get_PA_Curr(u8 ch)   
{
	double Curr;
	if(ch>1)return 0;
	if(ch==0)ADC_RegularChannelConfig(ADC3, 6, 1, ADC_SampleTime_480Cycles );
	else ADC_RegularChannelConfig(ADC3, 4, 1, ADC_SampleTime_480Cycles );
		    
	ADC_SoftwareStartConv(ADC3);		//使能指定的ADC1的软件转换启动功能	
	while(!ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC ));//等待转换结束
	Curr=ADC_GetConversionValue(ADC3);	//返回最近一次ADC1规则组的转换结果
	Curr=Curr*3.3/4096;
	return (Curr/0.15);	//由ADC值 换算电流
}


void CurrADC_Init(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
	ADC_CommonInitTypeDef ADC_CommonInitStructure;
	ADC_InitTypeDef       ADC_InitStructure;
	
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
  GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化  
 
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE);	  //ADC1复位
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE);	//复位结束	 
 
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz 
  ADC_CommonInit(&ADC_CommonInitStructure);//初始化
	
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式	
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测，使用软件触发
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐	
  ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 
  ADC_Init(ADC3, &ADC_InitStructure);//ADC初始化
	
	ADC_Cmd(ADC3, ENABLE);//开启AD转换器	
}			


//INTL_RS485(机内控制RS485)，绑定UART6
//挂载设备：前放PA*2
void INTL_UART_Init(uint32_t bound){
   //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE);
 
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_USART6); 
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_USART6); 
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOC,&GPIO_InitStructure); 

	USART_InitStructure.USART_BaudRate = bound;//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
  USART_Init(USART6, &USART_InitStructure); //初始化串口6
	
	USART_ITConfig(USART6,USART_IT_RXNE, ENABLE);//开启接收中断
	USART_ITConfig(USART6,USART_IT_IDLE, ENABLE);//开启空闲中断
	
  NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn;//串口6中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

	USART_Cmd(USART6, ENABLE);  //使能串口6
}
	  


//USART6中断处理函数
// INTL_RS485中断处理函数
void USART6_IRQHandler(void)                	
{
	uint8_t Res;
	if(USART_GetITStatus(USART6, USART_IT_RXNE) != RESET)  //接收到一个字节
	{
		Res =USART_ReceiveData(USART6);//读取1Byte
		if(INTL485_UART_Finish==0)//接收未完成
		{
			INTL485_UART_BUF[INTL485_UART_Count]=Res ;
			INTL485_UART_Count++;
		}   		 
  }
	else if(USART_GetITStatus(USART6, USART_IT_IDLE) != RESET)	//接收完成一帧
	{
		Res=USART6->SR;
		Res=USART6->DR;
		INTL485_UART_Finish=1;	//接收完成了
	}
}




